<cfcomponent output="false">
	<cfset $ = application.helpers />
	
	<!--- --->
	
	<cffunction name="getSession" access="public" output="true" returntype="query">
		
		<cfset var local = {} />
		
		<cfset local.session = application.g.sessionGateway.getSession() />

		<cfif local.session.recordcount eq 0>
			<!--- <cfset newSession() /> --->
			<cfset $.run.it('sessionService.newSession', {}) />
			<cfset local.session = application.g.sessionGateway.getSession()>
			<!--- just in case THAT doesn't work either --->
			<cfcookie name="clientID" value="-1" expires="now" />
			<cfset setClientID() />
			<cfset local.session = application.g.sessionGateway.getSession() />
		<cfelse>
			<!--- if existing session, update it's timestamp --->
			<cfset $.database.save(
				table="session",
				id=local.session.id,
				active = 1
			) />
		</cfif>

		<cfreturn local.session />
		
	</cffunction>
	
	<!--- --->
	
	<cffunction name="newSession" access="public" output="true" returntype="void">

		<cfset var local = {} />
		
		<cfset local.user = {} />
		<cfset local.user.id = "" />
		<cfset local.user.name="" />
		<cfset local.user.timezone = "-6:00" />
		<cfset local.user.DST = "true" />
		<cfset local.user.expireUTC = dateTimeFormat(now(),'mm/dd/yyyy HH:nn:ss') />
		<cfset local.user.sessionExpires = dateTimeFormat(dateAdd('h',1,now()),'mm/dd/yyyy HH:nn:ss') />
		<cfset local.user.admin = 0 />
		
		<cfset local.id = $.database.save(
			table="session",
			id="",
			client_id=$.format.decrypt(cookie.clientID),
			ip=$.format.decrypt(cookie.clientKey),
			json=serializeJSON(local.user)
		) />
		
	</cffunction>
	
	<!--- --->
	
	<cffunction name="setClientID" access="public" output="true" returntype="void">
		
		<cfset var local = {} />

		<cfif not structKeyExists(cookie,'clientID') or len($.format.decrypt(cookie.clientID)) neq 32>
			<cfset local.id = $.database.save(
				table="client",
				id=""
			) />
			<cfcookie name="clientID" expires="never" value="#$.format.encrypt(local.id)#" />
		</cfif>
		
		<cfif not structKeyExists(cookie,'clientKey')>
			<cfcookie name="clientKey" expires="never" value="#$.format.encrypt('unknown')#" />
		</cfif>
		
		<cfif not structKeyExists(cookie,'clientIDDecrypted')>
			<cfcookie name="clientIDDecrypted" expires="never" value="#$.format.decrypt(cookie.clientID)#" />
		</cfif>
		
	</cffunction>
	
	<!--- --->
	
	<cffunction name="recordClientIP" access="public" output="true" returntype="string">
		<cfargument name="ip" required="true" />
			
		<cfif arguments.ip neq ''>
			
			<!--- <cfset setClientID() /> --->
			<cfset $.run.it('sessionService, setClientID', {}) />
			
			<cfset $.database.save(
				table="client",
				id=$.format.decrypt(cookie.clientID),
				ip=arguments.ip
			) />

			<cfcookie name="clientKey" expires="never" value="#$.format.encrypt(arguments.ip)#" />
			<cfreturn arguments.ip />
		<cfelse>
			<cfreturn arguments.ip />
		</cfif>
		
	</cffunction>
	
	<!--- --->
	
	<cffunction name="evaluateSession" access="public" output="true" returntype="void">
			
		<cfset var local = {} />
		
		<!--- <cfset local.session = getSession() /> --->
		<cfset local.session = $.run.it('sessionService.getSession', {}) />
		
		<cfset _reflectSession(local.session) />

		<cfif len(session.user.id) eq 32>
			<cfset session.loggedin = true />
		<cfelse>
			<cfset session.loggedin = false />
		</cfif>
		
	</cffunction>
	
	<!--- --->
	
	<cffunction name="_reflectSession" access="private" output="true" returntype="void">
		<cfargument name="query" required="true" />
		<!--- moves the database session into session memory --->
		
		<cfset var local = {} />
		
		<!--- <cfset local.session = getSession() /> --->
		<cfset local.session = $.run.it('sessionService.getSession', {}) />

		<cfset session.user = {} />
		<cfset session.id = local.session.id />
		<cfset session.user.id = "" />
		<cfset session.user.name = "" />
		<cfset session.user.timezone = "-6:00" />
		<cfset session.user.DST = "true" />
		<cfset session.user.expireUTC = dateTimeFormat(now(),'mm/dd/yyyy HH:nn:ss') />
		<cfset session.user.sessionExpires = dateTimeFormat(dateAdd('h',1,now()),'mm/dd/yyyy HH:nn:ss') />
		<cfset session.user.admin = 0 />
		
		<cfif local.session.recordcount gt 0>
			<cfset session.user = deserializeJSON(local.session.json) />
			<cfif structKeyExists(session.user,"timezone") and session.user.timezone neq "">
				<cfset session.user.sessionTimeout = application.sessionTimeout />
				<Cfset session.user.sessionExpires = dateAdd("n",application.sessionTimeout,local.session.modified) />
			</cfif>
		</cfif>

		<cfif structKeyExists(session.user,"id") and len(session.user.id) eq 32>
			<cfset session.loggedin = true />
		<cfelse>
			<cfset session.loggedin = false />
		</cfif>
		
	</cffunction>
	
	<!--- --->
	
	<cffunction name="checkSession" access="public" output="true" returntype="struct">
		
		<cfset var local = {} />
		<cfset local.session = local.apples />
		<cfset local.session = application.g.sessionGateway.getSession() />
		
		<cfset local.result = {} />
		<cfset local.result.loggedIn = false />
		<cfset local.result.remaining = 0 />
		
		<cfif local.session.recordcount gt 0>
			<cfset local.result.loggedIn = true />
			<cfset local.result.expires = dateTimeFormat(dateAdd('n',application.sessionTimeout,local.session.modified),'mm/dd/yyyy HH:nn:ss') />
			<cfset local.result.now = dateTimeFormat(now()) />
			<cfset local.result.remaining = dateDiff('n',local.result.now,local.result.expires) />
		</cfif>
		
		<cfreturn local.result />
		
	</cffunction>
	
	<!--- --->
	
</cfcomponent> 